package com.springboot.demo.thread_pool;


import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

import com.springboot.demo.copy.Person;

/**
 * 线程池demo
 *
 * @author supu
 * @date 2019-03-25 13:44
 **/
public class ThreadPoolDemo {
    @Test
    public void test(){
        ThreadFactory threadFactory1 = Executors.defaultThreadFactory();
        ThreadFactory threadFactory2 = Executors.defaultThreadFactory();
//        BlockingQueue blockingQueue = new LinkedBlockingDeque(1);
        BlockingQueue blockingQueue = new ArrayBlockingQueue(10);
//        BlockingQueue blockingQueue = new SynchronousQueue();


        ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 10,
                TimeUnit.MILLISECONDS, blockingQueue, threadFactory1, new ThreadPoolExecutor.AbortPolicy());
        executor.allowCoreThreadTimeOut(true);

        ThreadPoolExecutor executor2 = new ThreadPoolExecutor(10, 20, 10,
                TimeUnit.MILLISECONDS, blockingQueue, threadFactory2, new ThreadPoolExecutor.AbortPolicy());
        executor2.allowCoreThreadTimeOut(true);

        for (int i = 0; i < 4; i++) {
            executor.execute(new CustomTask(i));
        }

        for (int i = 0; i < 4; i++) {
            executor2.execute(new CustomTask(i));
        }

        System.out.println("*******以下是threadPool运行参数*******************");

        System.out.println("poolSize:" + executor.getPoolSize());
        System.out.println("complatedTaskCount:" + executor.getCompletedTaskCount());
        System.out.println("taskCount:" + executor.getTaskCount());
        System.out.println("activeCount:" + executor.getActiveCount());
        System.out.println("queueSize:" + executor.getQueue().size());

        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("******************************");

        System.out.println("poolSize:" + executor.getPoolSize());
        System.out.println("complatedTaskCount:" + executor.getCompletedTaskCount());
        System.out.println("taskCount:" + executor.getTaskCount());
        System.out.println("activeCount:" + executor.getActiveCount());
        System.out.println("queueSize:" + executor.getQueue().size());
    }

    @Test
    public void customTest(){
        ThreadFactory threadFactory1 = new CustomThreadFactory("customPool");
        ThreadFactory threadFactory2 = new CustomThreadFactory("customPool");
//        BlockingQueue blockingQueue = new LinkedBlockingDeque(1);
        BlockingQueue blockingQueue = new ArrayBlockingQueue(10);
//        BlockingQueue blockingQueue = new SynchronousQueue();


        ThreadPoolExecutor executor = new CustomThreadPoolExecutor(10, 20, 10,
                TimeUnit.MILLISECONDS, blockingQueue, threadFactory1, new ThreadPoolExecutor.AbortPolicy());
        executor.allowCoreThreadTimeOut(true);

        ThreadPoolExecutor executor2 = new CustomThreadPoolExecutor(10, 20, 10,
                TimeUnit.MILLISECONDS, blockingQueue, threadFactory2, new ThreadPoolExecutor.AbortPolicy());
        executor2.allowCoreThreadTimeOut(true);

        for (int i = 0; i < 4; i++) {
            executor.execute(new CustomTask(i));
        }

        for (int i = 0; i < 4; i++) {
            executor2.execute(new CustomTask(i));
        }

        System.out.println("*******以下是threadPool运行参数*******************");

        System.out.println("poolSize:" + executor.getPoolSize());
        System.out.println("complatedTaskCount:" + executor.getCompletedTaskCount());
        System.out.println("taskCount:" + executor.getTaskCount());
        System.out.println("activeCount:" + executor.getActiveCount());
        System.out.println("queueSize:" + executor.getQueue().size());

        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("******************************");

        System.out.println("poolSize:" + executor.getPoolSize());
        System.out.println("complatedTaskCount:" + executor.getCompletedTaskCount());
        System.out.println("taskCount:" + executor.getTaskCount());
        System.out.println("activeCount:" + executor.getActiveCount());
        System.out.println("queueSize:" + executor.getQueue().size());
    }

    @Test
    public void testCallerRunsPolicy(){
        BlockingQueue blockingQueue = new ArrayBlockingQueue(1);
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(1,1,1,
                TimeUnit.SECONDS,blockingQueue,new ThreadPoolExecutor.CallerRunsPolicy());

        for (int i = 0; i < 4; i++) {
            poolExecutor.execute(new CustomTask(i));
        }
    }

    @Test
    public void testTaskFuture(){
        ThreadFactory threadFactory1 = new CustomThreadFactory("customPool");
        ExecutorService executor = Executors.newCachedThreadPool(threadFactory1);

        Person p1 = new Person();
        p1.setId(1);
        p1.setAge(1);
        p1.setName("1");

        Person p2 = new Person();
        p2.setId(2);
        p2.setAge(2);
        p2.setName("2");

        Person p3 = new Person();
        p3.setId(3);
        p3.setAge(3);
        p3.setName("3");

        Map<Integer,Future> resultMap = new HashMap<>(3);
        resultMap.put(p1.getId(),executor.submit(new CustomFuture(p1)));
        resultMap.put(p2.getId(),executor.submit(new CustomFuture(p2)));
        resultMap.put(p3.getId(),executor.submit(new CustomFuture(p3)));

        System.out.println("************");

        resultMap.forEach((k,v) -> {
            try {
                Person p = (Person) v.get();
                System.out.println(k + "---" + p);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });
    }
}
